package com.fly.demo.mybatis.config;

import java.util.Map;

import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.fly.demo.mybatis")
public class MybatisConfig
{
    
    @Bean
    public ConfigurationCustomizer mybatisConfigurationCustomizer()
    {
        return new ConfigurationCustomizer()
        {
            @Override
            public void customize(org.apache.ibatis.session.Configuration configuration)
            {
                configuration.setObjectWrapperFactory(new MapWrapperFactory());
            }
        };
    }
}

class MapWrapperFactory implements ObjectWrapperFactory
{
    @Override
    public boolean hasWrapperFor(Object object)
    {
        return object != null && object instanceof Map;
    }
    
    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object)
    {
        return new CustomWrapper(metaObject, (Map)object);
    }
}

class CustomWrapper extends MapWrapper
{
    public CustomWrapper(MetaObject metaObject, Map<String, Object> map)
    {
        super(metaObject, map);
    }
    
    @Override
    public String findProperty(String name, boolean useCamelCaseMapping)
    {
        return getCamelPropertyName(name);
    }
    
    private String getCamelPropertyName(String name)
    {
        if (name == null || "".equals(name))
        {
            return name;
        }
        String[] cols = name.split("_");
        StringBuilder buf = new StringBuilder(cols[0].toLowerCase());
        if (cols.length > 1)
        {
            for (int i = 1; i < cols.length; i++)
            {
                String str = cols[i];
                buf.append(str.substring(0, 1).toUpperCase());
                buf.append(str.substring(1).toLowerCase());
            }
        }
        return buf.toString();
    }
}